#pragma once 

#include <iostream>
#include <string>
#include <fstream>
#include <strings.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>

#define HTTP_VERSION "HTTP/1.0"
#define HOME_PAGE "wwwroot/index.html"

namespace ns_http
{
  class HttpServer
  {
    private:
      uint16_t port;
      int listen_sock;
    public:
      HttpServer(uint16_t _port)
        : port(_port)
         , listen_sock(-1)
      {}

      void InitHttpServer()
      {
        listen_sock = socket(AF_INET, SOCK_STREAM, 0);
        if(listen_sock < 0)
        {
          exit(2);
        }

        struct sockaddr_in local;
        bzero(&local, sizeof(local));
        local.sin_family = AF_INET;
        local.sin_port = htons(port);
        local.sin_addr.s_addr = INADDR_ANY;

        if(bind(listen_sock, (struct sockaddr*)&local, sizeof(local)) < 0)
        {
          std::cerr << "bind error" << std::endl;
          exit(3);
        }

        if(listen(listen_sock, 5) < 0)
        {
          exit(4);
        }
      }

      static void* HandlerRequest(void *args)
      {
        pthread_detach(pthread_self());
        int sock = *(int*)args;
        delete (int*)args;

        //debug
        //get request
        std::cout << "############################### begin: " << sock <<" ###########" << std::endl;
        char buffer[4096];
        ssize_t s = recv(sock, buffer, sizeof(buffer), 0);
        if(s > 0)
        {
          std::cout << buffer << std::endl;
        }
        std::cout << "############################### end: " << sock <<" ###########" << std::endl;
       
        //make response
        std::string response;
        std::string body;
        std::ifstream in(HOME_PAGE, std::ios::in | std::ios::binary);
        if(!in.is_open())
        {

        }
        else 
        {
          //成功
          std::string line;
          while(std::getline(in, line))
          {
            body += line;
          }
          response = HTTP_VERSION;
          response += " 200 OK\n";    //加上状态码200表示正常
          response += "Content-Type: text/html\n";
          response += ("Content-Length: " + std::to_string(body.size()) + "\n");

          response += "\n";
        
          response += body;
        }
        in.close();

        // std::string body = "<html><head><meta charset=\"UTF-8\"></head><body><h1>hello world</h1></body></html>";
        // std::string response = HTTP_VERSION;

        // response += " 200 OK\n";    //加上状态码200表示正常
        // response += "Content-Type: text/html\n";
        // response += ("Content-Length: " + std::to_string(body.size()) + "\n");

        // response += "\n";   //空行-用于区分报头和有效载荷

        // response += body;


        send(sock, response.c_str(), response.size(), 0);

        close(sock);    //基于短链接
        return nullptr;
      }
      void Loop()
      {
        while(true)
        {
          struct sockaddr_in peer;
          socklen_t len = sizeof(peer);
          int sock = accept(listen_sock, (struct sockaddr*)&peer, &len);
          if(sock < 0)
          {
            continue;
          }
          pthread_t tid;
          int *p = new int(sock);
          pthread_create(&tid, nullptr, HandlerRequest, p);
        }
      }

      ~HttpServer()
      {
        if(listen_sock >= 0)  close(listen_sock);
      }
  };
}
